import { useMemoizedFn } from 'ahooks';
import classNames from 'classnames';
import Lottie, { AnimationConfigWithData, RendererType } from 'lottie-web';
import React, { useLayoutEffect } from 'react';
import { useRef } from 'react';

export type NLottieProps<T extends RendererType = 'svg'> = {
  options: Omit<AnimationConfigWithData<T>, 'container'> & {
    onComplete?: () => void;
    onLoopComplete?: () => void;
    onEnterFrame?: () => void;
    onSegmentStart?: () => void;
    path?: string;
  };
  className?: string;
  style?: React.CSSProperties;
};
const NLottie = <T extends RendererType = 'svg'>({
  options: { onComplete, onLoopComplete, onEnterFrame, onSegmentStart, animationData, ...options },
  ...props
}: NLottieProps<T>) => {
  const ref = useRef<HTMLDivElement>(null);
  const complete = useMemoizedFn(() => onComplete?.());
  const loopComplete = useMemoizedFn(() => onLoopComplete?.());
  const enterFrame = useMemoizedFn(() => onEnterFrame?.());
  const segmentStart = useMemoizedFn(() => onSegmentStart?.());
  useLayoutEffect(() => {
    const rest: { path?: string; animationData?: any } = { animationData };
    // json资源打包改了这里处理下资源加载
    if (animationData && typeof animationData === 'string' && /\.json$/i.test(animationData)) {
      delete rest.animationData;
      rest.path = animationData;
    }

    const lottie = Lottie.loadAnimation({
      renderer: 'canvas',
      loop: true,
      autoplay: true,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice',
      },
      ...rest,
      ...options,
      container: ref.current!,
    });
    const events = {
      complete,
      loopComplete,
      enterFrame,
      segmentStart,
    } as const;
    (Object.keys(events) as (keyof typeof events)[]).forEach((name) => {
      lottie.addEventListener(name, events[name]);
    });
    return () => {
      (Object.keys(events) as (keyof typeof events)[]).forEach((name) => {
        lottie.removeEventListener(name, events[name]);
      });
      lottie?.destroy();
    };
  }, [animationData]);
  return <div {...props} className={classNames('size-full', props.className)} ref={ref} />;
};
export default React.memo(NLottie);
